package com.ctsi.ssdc.admin.service.impl;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import com.ctsi.ssdc.admin.domain.dto.*;
import com.ctsi.ssdc.admin.service.CscpUserService;
import com.ctsi.ssdc.security.SecurityUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ctsi.ssdc.admin.domain.CscpRoles;
import com.ctsi.ssdc.admin.domain.CscpUser;
import com.ctsi.ssdc.admin.domain.CscpUserDetail;
import com.ctsi.ssdc.admin.domain.CscpUserDetailExample;
import com.ctsi.ssdc.admin.domain.CscpUserDetailExample.Criteria;
import com.ctsi.ssdc.admin.domain.CscpUserDetailLike;
import com.ctsi.ssdc.admin.repository.CscpUserDetailRepository;
import com.ctsi.ssdc.admin.repository.CscpUserRepository;
import com.ctsi.ssdc.admin.repository.CscpUserRoleRepository;
import com.ctsi.ssdc.admin.service.CscpUserDetailService;
import com.ctsi.ssdc.admin.service.CscpUserRoleService;
import com.ctsi.ssdc.admin.service.mapper.CscpUserDetailMapper;
import com.ctsi.ssdc.model.PageResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * Service Implementation for managing CscpUserDetail.
 *
 * @author ctsi biyi generator
 *
 */
@Service
public class CscpUserDetailServiceImpl implements CscpUserDetailService {

    private final Logger log = LoggerFactory.getLogger(CscpUserDetailServiceImpl.class);
    
    @Value("${ctsi.login-password:ctsi1234}")
    private String RAW_PASSWORD;

    @Autowired
    private CscpUserDetailRepository cscpUserDetailRepository;

    private final CscpUserDetailMapper cscpUserDetailMapper;
    
    @Autowired
    private CscpUserRepository cscpUserRepository;
    
    @Autowired
    private CscpUserRoleRepository cscpUserRoleRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;

	@Autowired
	private CscpUserRoleService cscpUserRoleService;

	@Autowired
	private CscpUserService cscpUserService;

	public CscpUserDetailServiceImpl(CscpUserDetailMapper cscpUserDetailMapper) {
        this.cscpUserDetailMapper = cscpUserDetailMapper;
    }


	/**
	 * insert a cscpUserDetail.
	 *
	 * @param cscpUserDetailDTO
	 *            the entity to insert
	 * @return the persisted entity
	 */
	@Override
	@Transactional
	public CscpUserDetailDTO insert(CscpUserDetailDTO cscpUserDetailDTO) {
		log.debug("Request to insert CscpUserDetail : {}", cscpUserDetailDTO);

		CscpUser cscpUser = cscpUserDetailMapper.toCscpUser(cscpUserDetailDTO);
		cscpUser.setPassword(passwordEncoder.encode(RAW_PASSWORD));
		int userId = cscpUserRepository.insert(cscpUser);
		cscpUserDetailDTO.setUserId(cscpUser.getId());
		log.info("@@@@@@@@@@@@ insert user id is :" + userId);
		CscpUserDetail cscpUserDetail = cscpUserDetailMapper.toEntity(cscpUserDetailDTO);
		cscpUserDetail.setRegisterTime(new Date());
		cscpUserDetailRepository.insert(cscpUserDetail);
		// 保存用户角色
		cscpUserRoleService.saveUserRoles(cscpUserDetail.getUserId(), cscpUserDetailDTO.getRoles());
		return cscpUserDetailMapper.toDto(cscpUserDetail);
	}

	/**
	 * update a cscpUserDetail.
	 *
	 * @param cscpUserDetailDTO
	 *            the entity to update
	 * @return the persisted entity
	 */
	@Override
	@Transactional
	public CscpUserDetailDTO update(CscpUserDetailDTO cscpUserDetailDTO) {
		log.debug("Request to update CscpUserDetail : {}", cscpUserDetailDTO);
		CscpUserDetail cscpUserDetail = cscpUserDetailMapper.toEntity(cscpUserDetailDTO);
		
		cscpUserDetailRepository.updateByPrimaryKeySelective(cscpUserDetail);
		// 保存用户角色
		cscpUserRoleService.saveUserRoles(cscpUserDetailDTO.getUserId(), cscpUserDetailDTO.getRoles());
		
		return cscpUserDetailMapper.toDto(cscpUserDetail);
	}
	//增加当前管理员修改用户密码
	@Override
	public CscpUserDetailDTO userPwdUpdate(CscpUserUpdateDTO cscpUserUpdateDTO) throws Exception{
		CscpUserDetailDTO userDetailDTO = cscpUserUpdateDTO.getCscpUserDetailDTO();
		log.debug("Request to update CscpUserDetail : {}", userDetailDTO);
		String curPwd = cscpUserUpdateDTO.getCurrentUserPwd();
		if(!curPwd.isEmpty()){
			//获取当前登录人员id
			int uid = SecurityUtils.getCurrentUserId();
			//通过userId 获取当前用户用户名和密码
			CscpUserDTO currentUser = cscpUserService.findOne(uid);
			//输入管理员密码与实际密码不匹配
			if( !passwordEncoder.matches(cscpUserUpdateDTO.getCurrentUserPwd(), currentUser.getPassword())){
				throw new Exception("管理员密码不正确!");
			}
		}


		String newPwd = cscpUserUpdateDTO.getNewPassword();
		if(!newPwd.isEmpty()){
			//获取待修改用户的id
			Integer userId = userDetailDTO.getUserId();
			CscpUser cscpUser = cscpUserRepository.selectByPrimaryKey(userId);
			/*cscpUser.setPassword(passwordEncoder.encode(newPwd));
			//保存更新后密码
			cscpUserRepository.updateByPrimaryKey(cscpUser);*/


			CscpUserPasswordUpdate cscpUserPasswordUpdate = new CscpUserPasswordUpdate();
			cscpUserPasswordUpdate.setUserId(cscpUser.getId());
			cscpUserPasswordUpdate.setUserName(cscpUser.getUsername());
			cscpUserPasswordUpdate.setNewPassword(newPwd);
			cscpUserService.updatePassword(cscpUserPasswordUpdate,false);
		}

		CscpUserDetail cscpUserDetail = cscpUserDetailMapper.toEntity(userDetailDTO);
		//保存用户详细信息
		cscpUserDetailRepository.updateByPrimaryKeySelective(cscpUserDetail);
		// 保存用户角色
		cscpUserRoleService.saveUserRoles(userDetailDTO.getUserId(), userDetailDTO.getRoles());

		return cscpUserUpdateDTO.getCscpUserDetailDTO();
	}

	/**
	 * Get all the cscpUserDetails.
	 *
	 * @return the list of entities
	 */
	@Override
	@Transactional(readOnly = true)
	public PageResult<CscpUserDetailDTO> findAll() {
		log.debug("Request to get all CscpUserDetails");

		List<CscpUserDetailDTO> data = cscpUserDetailRepository.selectByExample(null).stream()
				.map(cscpUserDetailMapper::toDto).collect(Collectors.toCollection(LinkedList::new));

		long count = 0L;

		if (CollectionUtils.isNotEmpty(data)) {
			count = cscpUserDetailRepository.countByExample(null);
		}

		return new PageResult<CscpUserDetailDTO>(data, count, count);

	}

	/**
	 * Get one cscpUserDetail.
	 *
	 * @param id
	 *            the id of the entity
	 * @return the entity
	 */
	@Override
	@Transactional(readOnly = true)
	public CscpUserDetailDTO findOne(Integer id) {
		log.debug("Request to get CscpUserDetail : {} ", id);

		CscpUserDetail cscpUserDetail = cscpUserDetailRepository.selectByPrimaryKey(id);
		return cscpUserDetailMapper.toDto(cscpUserDetail);
	}

	/**
	 * Delete the cscpUserDetail .
	 *
	 * @param id
	 *            the id of the entity
	 */
	@Override
	public void delete(Integer id) {
		log.debug("Request to delete CscpUserDetail : {} ", id);

		cscpUserDetailRepository.deleteByPrimaryKey(id);
	}

	private String getPageOrderBy(Pageable page) {

		if (page != null && page.getSort() != null) {

			StringBuilder sb = new StringBuilder();

			page.getSort()
					.forEach(sort -> sb.append(sort.getProperty()).append(" ").append(sort.getDirection()).append(","));

			if (sb.length() > 1) {
				return (sb.substring(0, sb.length() - 1));
			}
		}

		return null;
	}

	/**
	 * Get the cscpUserDetails.
	 *
	 * @return the list of entities
	 */
	@Override
	@Transactional(readOnly = true)
	public PageResult<CscpUserDetailDTO> findByCscpUserDetailDTO(CscpUserDetailDTO cscpUserDetailDTO, Pageable page) {

		log.debug("Request to find CscpUserDetails");

		CscpUserDetailExample example = new CscpUserDetailExample();

		example.setPage(page);

		Criteria critieria = example.createCriteria();

		if (cscpUserDetailDTO.getId() != null) {
			critieria.andIdEqualTo(cscpUserDetailDTO.getId());
		}
		if (cscpUserDetailDTO.getUserId() != null) {
			critieria.andUserIdEqualTo(cscpUserDetailDTO.getUserId());
		}

		if (StringUtils.isNotBlank(cscpUserDetailDTO.getFamilyName())) {
			critieria.andFamilyNameLike(String.format("%%%s%%", cscpUserDetailDTO.getFamilyName()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getName())) {
			critieria.andNameLike(String.format("%%%s%%", cscpUserDetailDTO.getName()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getMobile())) {
			critieria.andMobileLike(String.format("%%%s%%", cscpUserDetailDTO.getMobile()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getEmail())) {
			critieria.andEmailLike(String.format("%%%s%%", cscpUserDetailDTO.getEmail()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getImgPath())) {
			critieria.andImgPathLike(String.format("%%%s%%", cscpUserDetailDTO.getImgPath()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getDiscTitle())) {
			critieria.andDiscTitleLike(String.format("%%%s%%", cscpUserDetailDTO.getDiscTitle()));
		}
		if (StringUtils.isNotBlank(cscpUserDetailDTO.getDiscDetail())) {
			critieria.andDiscDetailLike(String.format("%%%s%%", cscpUserDetailDTO.getDiscDetail()));
		}

		String orderBy = getPageOrderBy(page);

		if (StringUtils.isNotEmpty(orderBy)) {
			example.setOrderByClause(orderBy);
		}
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<CscpUserDetailDTO> data = cscpUserDetailMapper
				.toDto(cscpUserDetailRepository.selectByExamplewithPage(example));

		long count = 0L;

		if (CollectionUtils.isNotEmpty(data)) {
			count = cscpUserDetailRepository.countByExample(example);
		}

		return new PageResult<CscpUserDetailDTO>(data, count, count);

	}

	/**
	 * Get the cscpUserDetails.
	 *
	 * @param cscpUserDetailCriteria
	 * @param page
	 * @return
	 */
	@Transactional(readOnly = true)
	public PageResult<CscpUserDetailDTO> findByCscpUserDetailCriteria(CscpUserDetailCriteria cscpUserDetailCriteria,
			Pageable page) {

		CscpUserDetailExample example = new CscpUserDetailExample();

		example.setPage(page);

		Criteria criteria = example.createCriteria();

		if (cscpUserDetailCriteria != null) {
			cscpUserDetailCriteria.buildCriteria(criteria);
		}

		String orderBy = getPageOrderBy(page);

		if (StringUtils.isNotEmpty(orderBy)) {
			example.setOrderByClause(orderBy);
		}
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		List<CscpUserDetailDTO> data = cscpUserDetailMapper
				.toDto(cscpUserDetailRepository.selectByExamplewithPage(example));

		long count = 0L;

		if (CollectionUtils.isNotEmpty(data)) {
			count = cscpUserDetailRepository.countByExample(example);
		}

		return new PageResult<CscpUserDetailDTO>(data, count, count);

	}

	@Override
	public List<CscpUserDetailDTO> selectByWorkGroupId(Integer id) {
		// TODO Auto-generated method stub
		List<CscpUserDetail> list = cscpUserDetailRepository.selectByWorkGroupId(id);
		List<CscpUserDetailDTO> data = cscpUserDetailMapper.toDto(list);
		return data;
	}

	@Override
	public CscpUserDetailDTO selectByUserId(Integer userId) {
		// TODO Auto-generated method stub
		log.debug("Request to get CscpUserDetail by userId : {} ", userId);

		CscpUserDetail cscpUserDetail = cscpUserDetailRepository.selectByUserId(userId);
		return cscpUserDetailMapper.toDto(cscpUserDetail);
	}

	@Override
	public PageResult<CscpUserDetailDTO> findByCscpUserDetailDTOOr(CscpUserDetailLike cscpUserDetailLike, Pageable page) {
		
		log.debug("Request to find CscpUserDetail");
		
		String orderBy = getPageOrderBy(page);
		
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		
		List<CscpUserDetailDTO> list = cscpUserDetailRepository.queryUserDetailPreventSQLAttack(cscpUserDetailLike.getUsernameLike()
				,cscpUserDetailLike.getFamilyNameLike(),
				cscpUserDetailLike.getNameLike(),cscpUserDetailLike.getMobileLike(),cscpUserDetailLike.getEmailLike(),
				cscpUserDetailLike.getDiscTitleLike(),cscpUserDetailLike.getDiscDetailLike(),
				orderBy);
		PageInfo<CscpUserDetailDTO> info = new PageInfo<>(list);
		if(list!=null) {
			for(int index=0; index<list.size(); index++) {
				//用户的角色信息
				List<CscpRoles> roleList = cscpUserRoleRepository.queryRoleByUserId(list.get(index).getUserId());
				if(roleList!=null && roleList.size()>0) {
					StringBuilder roleId = new StringBuilder(roleList.get(0).getId().toString());
					StringBuilder roleName = new StringBuilder(roleList.get(0).getName());
					for(int i=1; i<roleList.size(); i++) {
						//","方式分割：如1，2  ；admin，admin2
						roleId.append(","+roleList.get(i).getId());
						roleName.append(","+roleList.get(i).getName());
					}
					list.get(index).setRoleIds(roleId.toString());
					list.get(index).setRoleNames(roleName.toString());
				}
			}
		}
		
		return new PageResult<CscpUserDetailDTO>(list, info.getTotal(), info.getTotal());   
		
	}
	
	@Deprecated
	@Override
	@Transactional(readOnly = true)
	public PageResult<CscpUserDetailDTO> findByUserId(String userId, Pageable page) {
		
		String orderBy = getPageOrderBy(page);
		
		PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		//用户信息
		List<CscpUserDetailDTO> list = cscpUserDetailRepository.queryUserDetailByUserId(userId, orderBy);

		PageInfo<CscpUserDetailDTO> info = new PageInfo<>(list);
		
		if(list!=null) {
			for(int index=0; index<list.size(); index++) {
				//用户的角色信息
				List<CscpRoles> roleList = cscpUserRoleRepository.queryRoleByUserId(list.get(index).getUserId());
				if(roleList!=null && roleList.size()>0) {
					StringBuilder idsb = new StringBuilder(roleList.get(0).getId().toString());
					StringBuilder namesb = new StringBuilder(roleList.get(0).getName());
					for(int i=1; i<roleList.size(); i++) {
						idsb.append(","+roleList.get(i).getId());//1,2
						namesb.append(","+roleList.get(i).getName());//admin,system
					}
					list.get(index).setRoleIds(idsb.toString());
					list.get(index).setRoleNames(namesb.toString());
				}
			}
		}

		return new PageResult<CscpUserDetailDTO>(list, info.getTotal(), info.getTotal());
	}
	
	@Override
	public CscpUserDetailDTO findByUserId(Integer userId) {
		//用户信息
		CscpUserDetailDTO userDetailDTO = cscpUserDetailRepository.queryByUserId(userId);
		if(userDetailDTO!=null) {
			//用户的角色信息
			List<CscpRoles> roleList = cscpUserRoleRepository.queryRoleByUserId(userDetailDTO.getUserId());
			if(roleList!=null && roleList.size()>0) {
				StringBuilder idsb = new StringBuilder(roleList.get(0).getId().toString());
				StringBuilder namesb = new StringBuilder(roleList.get(0).getName());
				for(int i=1; i<roleList.size(); i++) {
					idsb.append(","+roleList.get(i).getId());//1,2
					namesb.append(","+roleList.get(i).getName());//admin,system
				}
				userDetailDTO.setRoleIds(idsb.toString());
				userDetailDTO.setRoleNames(namesb.toString());
			}
		}
		return userDetailDTO;
	}

}
